import { PropType, Ref, computed, defineComponent, provide, ref, watch } from "vue";
import Item from "./Item";

export const ListContext = Symbol('ListContext');

export interface ListProps {
    border?: boolean,
    size?: 'small'|'large',
    head?: any,
    foot?: any,
    selectable?: boolean,
    activeKey: string | number,
}

export type ListContextProps = {
    selectable?: boolean,
    activeKey: Ref<string | number>,
    setActiveKey?: (key: string | number) => void,
    onSelect?: (item: any) => void,
}

const List = defineComponent({
    name: 'List',
    props: {
        border: {
            type: Boolean,
        },
        size: {
            type: String as () => 'small'|'large',
        },
        head: {
            type: [String, Object] as PropType<ListProps['head']>
        },
        foot: {
            type: [String, Object] as PropType<ListProps['foot']>
        },
        activeKey: {
            type: [String, Number] as PropType<ListProps['activeKey']>
        },
        selectable: {
            type: Boolean as PropType<ListProps['selectable']>,
        }
    },
    emits: ['update:activeKey', 'select'],
    setup (props, { slots, emit }) {
        const classList = computed(() => ({
            'cm-list': true,
            'cm-list-border': props.border,
            'cm-list-selectable': props.selectable,
            [`cm-list-${props.size}`]: props.size
        }));
        const activeKey = ref(props.activeKey);

        const setActiveKey = (key: string | number) => {
            activeKey.value = key;
            emit('update:activeKey', key);
        };

        watch(() => props.activeKey, (newVal) => {
            activeKey.value = newVal;
        });

        provide(ListContext, {
            activeKey,
            selectable: props.selectable,
            setActiveKey,
            onSelect: (data) => {
                emit('select', data);
            }
        });

        return () =>
            <div class={classList.value}>
                {
                    props.head || slots.head ? <div class="cm-list-head">{props.head || (slots.head?.())}</div> : null
                }
                {slots.default?.()}
                {
                    props.foot || slots.foot ? <div class="cm-list-foot">{props.foot || (slots.foot?.())}</div> : null
                }
            </div>;
    }
});

List.Item = Item;

export default List;
